package com.yeziji.dynamicConfig.base;

import cn.hutool.core.util.ReflectUtil;
import com.yeziji.utils.expansion.Lists2;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;

import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 环境工厂
 *
 * @author hwy
 * @since 2023/12/13 10:54
 **/
@Slf4j
public class EnvironmentFactory implements EnvironmentAware {
    private String applicationName;
    protected final boolean printLog;
    protected static ConfigurableEnvironment ENVIRONMENT;

    public EnvironmentFactory(boolean printLog) {
        this.printLog = printLog;
    }

    /**
     * 获取 originalTracked 的配置信息
     *
     * @return {@link List} 配置元素列表
     */
    protected List<ConfigMeta> getConfigMeta() {
        List<ConfigMeta> result = new ArrayList<>();
        List<OriginTrackedMapPropertySource> originTrackedMapPropertySources = this.getOriginTrackedMapPropertySources();
        if (Lists2.isNotEmpty(originTrackedMapPropertySources)) {
            for (OriginTrackedMapPropertySource originTrackedMapPropertySource : originTrackedMapPropertySources) {
                Map<String, Object> source = originTrackedMapPropertySource.getSource();
                for (Map.Entry<String, Object> entry : source.entrySet()) {
                    result.add(new ConfigMeta(originTrackedMapPropertySource.getName(), entry.getKey(), entry.getValue()));
                }
            }
        }
        return result;
    }

    /**
     * 获取原来的配置资源
     *
     * @return {@link OriginTrackedMapPropertySource} 资源配置
     */
    protected List<OriginTrackedMapPropertySource> getOriginTrackedMapPropertySources() {
        MutablePropertySources propertySources = ENVIRONMENT.getPropertySources();
        List<PropertySource<?>> propertySourceList =
                (List<PropertySource<?>>) ReflectUtil.getFieldValue(propertySources, "propertySourceList");
        List<OriginTrackedMapPropertySource> result = new ArrayList<>();
        for (PropertySource<?> propertySource : propertySourceList) {
            if (propertySource instanceof OriginTrackedMapPropertySource) {
                if (this.applicationName == null) {
                    this.applicationName = propertySource.getName();
                }
                result.add((OriginTrackedMapPropertySource) propertySource);
            }
        }
        return result;
    }

    @Override
    public void setEnvironment(@Nonnull Environment environment) {
        EnvironmentFactory.ENVIRONMENT = (ConfigurableEnvironment) environment;
    }
}
